package com.nfdw.project.service.impl;

import com.nfdw.project.core.AbstractService;
import com.nfdw.project.dao.SaleUsersProfitAndLoseTotalInfoMapper;
import com.nfdw.project.dto.SaleUsersProfitAndLoseInfoDto;
import com.nfdw.project.enums.CompanyTypeEnum;
import com.nfdw.project.enums.SaleTypeEnum;
import com.nfdw.project.model.SaleUsersProfitAndLoseTotalInfo;
import com.nfdw.project.service.DemandResponseSaleUsersProfitAndLoseInfoService;
import com.nfdw.project.service.ElectricEnergySaleUsersProfitAndLoseInfoService;
import com.nfdw.project.service.SaleUsersProfitAndLoseTotalInfoService;
import com.nfdw.project.vo.RetailUserTradeSettleTotalInfoVo;
import com.nfdw.project.vo.SaleUsersProfitAndLoseInfoVo;
import com.nfdw.project.vo.TradePowerAndIncomeInfoVo;
import com.nfdw.project.vo.TradeProfitAndLossInfoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.util.ObjectUtils;

import javax.annotation.Resource;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Service
@Transactional
public class SaleUsersProfitAndLoseTotalInfoServiceImpl extends AbstractService<SaleUsersProfitAndLoseTotalInfo> implements SaleUsersProfitAndLoseTotalInfoService {

    @Autowired
    private ElectricEnergySaleUsersProfitAndLoseInfoService electricEnergySaleUsersProfitAndLoseInfoService;
    @Autowired
    private DemandResponseSaleUsersProfitAndLoseInfoService demandResponseSaleUsersProfitAndLoseInfoService;
    @Resource
    private SaleUsersProfitAndLoseTotalInfoMapper saleUsersProfitAndLoseTotalInfoMapper;

    @Override
    public SaleUsersProfitAndLoseInfoVo tradeSettleInfo(SaleUsersProfitAndLoseInfoDto param) {
        SaleUsersProfitAndLoseInfoVo  saleUsersProfitAndLoseInfoVo;
        //判断参数空情况

        if(SaleTypeEnum.ELECTRICENERGY_SALE.getType().equals(param.getType())){
            //电能量交易盈亏情况
            saleUsersProfitAndLoseInfoVo = electricEnergySaleUsersProfitAndLoseInfoService.tradeSettleInfo(param);
        }else{
            //需求响应交易盈亏情况
            saleUsersProfitAndLoseInfoVo = demandResponseSaleUsersProfitAndLoseInfoService.tradeSettleInfo(param);
        }
        Optional<SaleUsersProfitAndLoseInfoVo> entity = Optional.ofNullable(saleUsersProfitAndLoseInfoVo);
        return entity.orElse(new SaleUsersProfitAndLoseInfoVo());
    }

    @Override
    public TradePowerAndIncomeInfoVo tradePowerAndIncome(SaleUsersProfitAndLoseInfoDto param) {

        List<TradePowerAndIncomeInfoVo.TradePowerVo> tradePowerVos;
        List<TradePowerAndIncomeInfoVo.KilowattIncomeVo> kilowattIncomeVos;
        List<TradePowerAndIncomeInfoVo.KilowattIncomePercentVo> kilowattIncomePercentVoList;
        if(SaleTypeEnum.ELECTRICENERGY_SALE.getType().equals(param.getType())){
            //代理用户用电量
            tradePowerVos = electricEnergySaleUsersProfitAndLoseInfoService.tradePowerInfo(param);
            //平均度电收益
            kilowattIncomeVos= electricEnergySaleUsersProfitAndLoseInfoService.kilowattIncomeInfo(param);
            //度电收益比平均度电收益情况
            kilowattIncomePercentVoList = electricEnergySaleUsersProfitAndLoseInfoService.kilowattIncomePercent(param);
        }else{
            //代理用户用电量
            tradePowerVos = demandResponseSaleUsersProfitAndLoseInfoService.tradePowerInfo(param);
            //平均度电收益
            kilowattIncomeVos= demandResponseSaleUsersProfitAndLoseInfoService.kilowattIncomeInfo(param);
            //度电收益比平均度电收益情况
            kilowattIncomePercentVoList = demandResponseSaleUsersProfitAndLoseInfoService.kilowattIncomePercent(param);
        }
        //代理用户用电量数据组装
        ArrayList<BigDecimal> monTradePower = new ArrayList<>(Collections.nCopies(4, BigDecimal.ZERO));
        ArrayList<BigDecimal> yearTradEPower = new ArrayList<>(Collections.nCopies(4, BigDecimal.ZERO));
        ArrayList<BigDecimal> powerBasisRatio = new ArrayList<>(Collections.nCopies(4, BigDecimal.ZERO));
        for(int i=0;i<tradePowerVos.size();i++){
            Integer index = CompanyTypeEnum.findIndex(tradePowerVos.get(i).getCompanyType());
            monTradePower.set(index, tradePowerVos.get(i).getMonTradePower());
            yearTradEPower.set(index, tradePowerVos.get(i).getYearTradEPower());
            powerBasisRatio.set(index,tradePowerVos.get(i).getYearTradEPower());
        }
        TradePowerAndIncomeInfoVo.TradePowerArrVo tradePowerArrVo = new TradePowerAndIncomeInfoVo.TradePowerArrVo();
        tradePowerArrVo.setMonTradePowerArr(monTradePower);
        tradePowerArrVo.setYearTradEPowerArr(yearTradEPower);
        tradePowerArrVo.setPowerBasisRatioArr(powerBasisRatio);

        //平均度电收益数据组装
        ArrayList<BigDecimal> monTradeIncome = new ArrayList<>(Collections.nCopies(4, BigDecimal.ZERO));
        ArrayList<BigDecimal> yearTradeIncome = new ArrayList<>(Collections.nCopies(4, BigDecimal.ZERO));
        for(int i=0;i<tradePowerVos.size();i++){
            Integer index = CompanyTypeEnum.findIndex(tradePowerVos.get(i).getCompanyType());
            monTradeIncome.set(index, kilowattIncomeVos.get(i).getMonKilowattIncome());
            yearTradeIncome.set(index, kilowattIncomeVos.get(i).getYearKilowattIncome());
        }
        TradePowerAndIncomeInfoVo.KilowattIncomeArrVo kilowattIncomeArrVo = new TradePowerAndIncomeInfoVo.KilowattIncomeArrVo();
        kilowattIncomeArrVo.setMonKilowattIncomeArr(monTradeIncome);
        kilowattIncomeArrVo.setYearKilowattIncomeArr(yearTradeIncome);

        //度电收益比平均度电收益情况数据组装
        ArrayList<Integer> minusTwentyPercentArr = new ArrayList<>(Collections.nCopies(4, 0));
        ArrayList<Integer> minusTenToTwentyPercentArr = new ArrayList<>(Collections.nCopies(4, 0));
        ArrayList<Integer> tenToTwentyPercentArr = new ArrayList<>(Collections.nCopies(4, 0));
        ArrayList<Integer> twentyPercentArr = new ArrayList<>(Collections.nCopies(4, 0));
        for(int i=0;i<tradePowerVos.size();i++){
            Integer index = CompanyTypeEnum.findIndex(kilowattIncomePercentVoList.get(i).getCompanyType());
            minusTwentyPercentArr.set(index, kilowattIncomePercentVoList.get(i).getMinusTwentyPercent());
            minusTenToTwentyPercentArr.set(index, kilowattIncomePercentVoList.get(i).getMinusTenToTwentyPercent());
            tenToTwentyPercentArr.set(index, kilowattIncomePercentVoList.get(i).getTenToTwentyPercent());
            twentyPercentArr.set(index, kilowattIncomePercentVoList.get(i).getTwentyPercent());
        }
        TradePowerAndIncomeInfoVo.KilowattIncomePercentArrVo kilowattIncomePercentArrVo = new TradePowerAndIncomeInfoVo.KilowattIncomePercentArrVo();
        kilowattIncomePercentArrVo.setMinusTwentyPercentArr(minusTwentyPercentArr);
        kilowattIncomePercentArrVo.setTenToTwentyPercentArr(tenToTwentyPercentArr);
        kilowattIncomePercentArrVo.setMinusTenToTwentyPercentArr(minusTenToTwentyPercentArr);
        kilowattIncomePercentArrVo.setTwentyPercentArr(twentyPercentArr);

        return TradePowerAndIncomeInfoVo.builder()
                //代理用户用电量
                .tradePowerArrVo(tradePowerArrVo)
                //平均度电收益
                .kilowattIncomeArrVo(kilowattIncomeArrVo)
                //度电收益比平均度电收益情况
                .kilowattIncomePercentArrVo(kilowattIncomePercentArrVo)
                .build();
    }

    @Override
    public TradeProfitAndLossInfoVo tradeProfitAndLoss(SaleUsersProfitAndLoseInfoDto param) {
        List<TradeProfitAndLossInfoVo.TradeProfitVo> tradeProfitVos;
        List<TradeProfitAndLossInfoVo.TradeLossVo> tradeLossVos;

        //电能源交易
        if(SaleTypeEnum.ELECTRICENERGY_SALE.getType().equals(param.getType())){
            //盈利情况
            tradeProfitVos = electricEnergySaleUsersProfitAndLoseInfoService.tradeProfit(param);
            //亏损情况
            tradeLossVos = electricEnergySaleUsersProfitAndLoseInfoService.tradeLoss(param);

        //需求响应交易
        }else{
            //盈利情况
            tradeProfitVos = demandResponseSaleUsersProfitAndLoseInfoService.tradeProfit(param);
            //亏损情况
            tradeLossVos = demandResponseSaleUsersProfitAndLoseInfoService.tradeLoss(param);
        }

        //盈利情况
        ArrayList<Integer> monProfitUsersNumArr = new ArrayList<>(Collections.nCopies(4, 0));
        ArrayList<Integer> yearProfitUsersNumArr = new ArrayList<>(Collections.nCopies(4, 0));
        ArrayList<BigDecimal> monProfitMoneyArr = new ArrayList<>(Collections.nCopies(4, BigDecimal.ZERO));
        ArrayList<BigDecimal> yearProfitMoneyArr = new ArrayList<>(Collections.nCopies(4, BigDecimal.ZERO));
        for(int i=0;i<tradeProfitVos.size();i++){
            Integer index = CompanyTypeEnum.findIndex(tradeProfitVos.get(i).getCompanyType());
            monProfitUsersNumArr.set(index, tradeProfitVos.get(i).getMonProfitUsersNum());
            yearProfitUsersNumArr.set(index, tradeProfitVos.get(i).getYearProfitUsersNum());
            monProfitMoneyArr.set(index,tradeProfitVos.get(i).getMonProfitMoney());
            yearProfitMoneyArr.set(index,tradeProfitVos.get(i).getYearProfitMoney());
        }
        TradeProfitAndLossInfoVo.TradeProfitArr tradeProfitArr = new TradeProfitAndLossInfoVo.TradeProfitArr();
        tradeProfitArr.setMonProfitMoneyArr(monProfitMoneyArr);
        tradeProfitArr.setMonProfitUsersNumArr(monProfitUsersNumArr);
        tradeProfitArr.setYearProfitMoneyArr(yearProfitMoneyArr);
        tradeProfitArr.setYearProfitUsersNumArr(yearProfitUsersNumArr);

        //亏损情况
        ArrayList<Integer> monLossUsersNumArr = new ArrayList<>(Collections.nCopies(4, 0));
        ArrayList<Integer> yearLossUsersNumArr = new ArrayList<>(Collections.nCopies(4, 0));
        ArrayList<BigDecimal> monLossMoneyArr = new ArrayList<>(Collections.nCopies(4, BigDecimal.ZERO));
        ArrayList<BigDecimal> yearLossMoneyArr = new ArrayList<>(Collections.nCopies(4, BigDecimal.ZERO));
        for(int i=0;i<tradeLossVos.size();i++){
            Integer index = CompanyTypeEnum.findIndex(tradeLossVos.get(i).getCompanyType());
            monLossMoneyArr.set(index,tradeLossVos.get(i).getMonLossMoney());
            monLossUsersNumArr.set(index, tradeLossVos.get(i).getMonLossUsersNum());
            yearLossUsersNumArr.set(index, tradeLossVos.get(i).getYearLossUsersNum());
            yearLossMoneyArr.set(index,tradeLossVos.get(i).getYearLossMoney());
        }
        TradeProfitAndLossInfoVo.TradeLossArr tradeLossArr = new TradeProfitAndLossInfoVo.TradeLossArr();
        tradeLossArr.setMonLossMoneyArr(monLossMoneyArr);
        tradeLossArr.setMonLossUsersNumArr(monLossUsersNumArr);
        tradeLossArr.setYearLossMoneyArr(yearLossMoneyArr);
        tradeLossArr.setYearLossUsersNumArr(yearLossUsersNumArr);

        return TradeProfitAndLossInfoVo.builder()
                .tradeProfitArr(tradeProfitArr)
                .tradeLossArr(tradeLossArr).build();
    }

}
